<template>
  <div class="csv-graph-uploader">
    <!-- 文件上传区域 -->
    <div v-if="!graphData || graphData.nodes.length === 0" class="upload-section">
      <h3>📁 上传CSV文件</h3>
      
      <div 
        class="upload-area"
        :class="{ 'drag-over': isDragOver }"
        @click="triggerFileInput"
        @dragover="handleDragOver"
        @dragleave="handleDragLeave"
        @drop="handleDrop">
        
        <div v-if="!selectedFile" class="upload-content">
          <div class="upload-icon">📊</div>
          <h4>拖拽CSV文件到此处或点击选择</h4>
          <p>支持拖拽上传，文件大小不超过10MB</p>
          <div class="upload-hint">
            支持的格式：.csv
          </div>
        </div>
        
        <div v-else class="file-info">
          <h4>✅ 已选择文件</h4>
          <p><strong>文件名：</strong>{{ selectedFile.name }}</p>
          <p><strong>文件大小：</strong>{{ formatFileSize(selectedFile.size) }}</p>
          <p><strong>文件类型：</strong>{{ selectedFile.type || 'text/csv' }}</p>
          <div class="file-actions">
            <button @click.stop="processFile" class="btn btn-primary" :disabled="isProcessing">
              <span v-if="isProcessing" class="loading-spinner-small"></span>
              {{ isProcessing ? '处理中...' : '开始处理' }}
            </button>
            <button @click.stop="resetUpload" class="btn btn-secondary">重新选择</button>
          </div>
        </div>
      </div>
      
      <input 
        ref="fileInput"
        type="file"
        accept=".csv"
        @change="handleFileSelect"
        style="display: none;">
    </div>

    <div v-if="graphData && graphData.nodes.length > 0" class="graph-section">
      <div class="graph-stats">
        <h4>📈 数据统计</h4>
        <div class="stats-grid">
          <div class="stat-item">
            <span class="stat-label">总行数:</span>
            <span class="stat-value">{{ graphData.stats.total_rows }}</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">总列数:</span>
            <span class="stat-value">{{ graphData.stats.total_columns }}</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">数值列:</span>
            <span class="stat-value">{{ graphData.stats.numeric_columns }}</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">分类列:</span>
            <span class="stat-value">{{ graphData.stats.categorical_columns }}</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">缺失数据:</span>
            <span class="stat-value">{{ graphData.stats.missing_data_percentage.toFixed(1) }}%</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">连线数:</span>
            <span class="stat-value">{{ graphData.links.length }}</span>
          </div>
        </div>
      </div>
      
      <div class="graph-container">
        <SimpleD3Graph :data="graphData" />
      </div>
    </div>

    <div v-if="errorMessage" class="error-message">
      <h4>❌ 错误信息</h4>
      <p>{{ errorMessage }}</p>
      <button @click="clearError" class="btn btn-secondary">清除错误</button>
    </div>

    <div v-if="!isBackendConnected" class="backend-warning">
      <h4>⚠️ 后端服务未连接</h4>
      <p>请确保Graph Backend服务正在运行 (http://localhost:5000)</p>
      <button @click="checkBackendConnection" class="btn btn-secondary">重新检查</button>
    </div>

    <!-- 关系管理部分 -->
    <div v-if="graphData && graphData.nodes.length > 0" class="relationship-management">
      <h3>🔗 关系管理</h3>
      
      <!-- 添加关系 -->
      <div class="add-relationship">
        <h4>添加新关系</h4>
        <div class="form-row">
          <select v-model="newRelationship.source" class="form-select">
            <option value="">选择源节点</option>
            <option v-for="node in graphData.nodes" :key="node.id" :value="node.id">
              {{ node.name || node.id }}
            </option>
          </select>
          <select v-model="newRelationship.target" class="form-select">
            <option value="">选择目标节点</option>
            <option v-for="node in graphData.nodes" :key="node.id" :value="node.id">
              {{ node.name || node.id }}
            </option>
          </select>
          <input 
            v-model="newRelationship.relationship" 
            type="text" 
            placeholder="关系类型" 
            class="form-input">
          <button @click="addRelationship" class="btn btn-primary" :disabled="!canAddRelationship">
            添加关系
          </button>
        </div>
      </div>

      <!-- 关系列表 -->
      <div class="relationship-list">
        <h4>现有关系</h4>
        <div class="table-container">
          <table class="relationship-table">
            <thead>
              <tr>
                <th>源节点</th>
                <th>目标节点</th>
                <th>关系</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(link, index) in graphData.links" :key="index">
                <td>{{ getNodeName(link.source) }}</td>
                <td>{{ getNodeName(link.target) }}</td>
                <td>
                  <input 
                    v-model="link.relationship" 
                    type="text" 
                    class="relationship-input"
                    @change="updateRelationshipType(index, $event.target.value)"
                    placeholder="无">
                </td>
                <td>
                  <button @click="deleteRelationship(index)" class="btn btn-danger btn-sm">
                    删除
                  </button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
        
        <!-- 开始处理按钮 -->
        <div class="process-actions">
          <button 
            @click="startProcessing" 
            class="btn btn-success btn-lg"
            :disabled="isProcessingRelationships || graphData.links.length === 0">
            <span v-if="isProcessingRelationships" class="loading-spinner-small"></span>
            {{ isProcessingRelationships ? '处理中...' : '开始处理' }}
          </button>
          <p class="process-hint">
            点击开始处理按钮将根据当前关系配置重新生成图形
          </p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import SimpleD3Graph from './SimpleD3Graph.vue'

export default {
  name: 'CsvGraphUploader',
  components: {
    SimpleD3Graph
  },
  data() {
    return {
      selectedFile: null,
      isProcessing: false,
      isDragOver: false,
      graphData: null,
      errorMessage: '',
      isBackendConnected: true,
      backendUrl: 'http://localhost:5000',
      isProcessingRelationships: false,
      newRelationship: {
        source: '',
        target: '',
        relationship: '无'
      }
    }
  },
  computed: {
    canAddRelationship() {
      return this.newRelationship.source && 
             this.newRelationship.target && 
             this.newRelationship.source !== this.newRelationship.target
    }
  },
  mounted() {
    this.checkBackendConnection()
  },
  methods: {
    async checkBackendConnection() {
      try {
        const response = await fetch(`${this.backendUrl}/api/health`)
        this.isBackendConnected = response.ok
        if (!this.isBackendConnected) {
          this.errorMessage = '无法连接到后端服务，请确保Graph Backend正在运行'
        }
      } catch (error) {
        this.isBackendConnected = false
        this.errorMessage = '无法连接到后端服务，请确保Graph Backend正在运行'
      }
    },

    triggerFileInput() {
      this.$refs.fileInput.click()
    },

    handleFileSelect(event) {
      const file = event.target.files[0]
      if (file) {
        this.selectedFile = file
        this.clearError()
      }
    },

    handleDragOver(event) {
      event.preventDefault()
      this.isDragOver = true
    },

    handleDragLeave(event) {
      event.preventDefault()
      this.isDragOver = false
    },

    handleDrop(event) {
      event.preventDefault()
      this.isDragOver = false
      
      const files = event.dataTransfer.files
      if (files.length > 0) {
        const file = files[0]
        if (file.type === 'text/csv' || file.name.toLowerCase().endsWith('.csv')) {
          this.selectedFile = file
          this.clearError()
        } else {
          this.errorMessage = '请选择CSV文件'
        }
      }
    },

    async processFile() {
      if (!this.selectedFile) {
        this.errorMessage = '请先选择CSV文件'
        return
      }

      if (!this.isBackendConnected) {
        this.errorMessage = '后端服务未连接，无法处理文件'
        return
      }

      this.isProcessing = true
      this.clearError()

      try {
        const formData = new FormData()
        formData.append('file', this.selectedFile)

        const response = await fetch(`${this.backendUrl}/api/upload-csv`, {
          method: 'POST',
          body: formData
        })

        const result = await response.json()

        if (result.success) {
          this.graphData = result
          // 保存原始文件数据，以防selectedFile丢失
          this.graphData.originalFile = this.selectedFile
          this.$emit('graph-generated', result)
        } else {
          this.errorMessage = result.message || '处理CSV文件时出错'
        }
      } catch (error) {
        console.error('处理文件时出错:', error)
        this.errorMessage = `处理文件时出错: ${error.message}`
      } finally {
        this.isProcessing = false
      }
    },

    formatFileSize(bytes) {
      if (bytes === 0) return '0 Bytes'
      const k = 1024
      const sizes = ['Bytes', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },

    clearError() {
      this.errorMessage = ''
    },

    resetUpload() {
      this.selectedFile = null
      this.graphData = null
      this.clearError()
      this.$refs.fileInput.value = ''
    },

    loadStoredData(graphData) {
      this.graphData = graphData
      // 注意：从sessionStorage加载的数据中，originalFile会丢失
      // 因为File对象无法序列化到JSON中
      console.log('加载存储的数据，originalFile已丢失:', this.graphData.originalFile)
      this.$emit('graph-generated', graphData)
    },

    // 关系管理方法
    getNodeName(node) {
      if (typeof node === 'string') {
        const foundNode = this.graphData.nodes.find(n => n.id === node)
        return foundNode ? (foundNode.name || foundNode.id) : node
      }
      return node.name || node.id
    },

    addRelationship() {
      if (!this.canAddRelationship) {
        this.errorMessage = '请填写完整的关系信息'
        return
      }

      // 检查关系是否已存在
      const existingLink = this.graphData.links.find(link => 
        link.source === this.newRelationship.source && 
        link.target === this.newRelationship.target
      )

      if (existingLink) {
        this.errorMessage = '该关系已存在'
        return
      }

      // 添加新关系
      const newLink = {
        source: this.newRelationship.source,
        target: this.newRelationship.target,
        relationship: this.newRelationship.relationship || '无'
      }

      this.graphData.links.push(newLink)
      
      // 重置表单
      this.newRelationship = {
        source: '',
        target: '',
        relationship: '无'
      }

      this.clearError()
      this.$emit('graph-updated', this.graphData)
    },

    deleteRelationship(index) {
      if (confirm('确定要删除这个关系吗？')) {
        this.graphData.links.splice(index, 1)
        this.$emit('graph-updated', this.graphData)
      }
    },

    updateRelationshipType(index, newRelationship) {
      this.graphData.links[index].relationship = newRelationship || '无'
      this.$emit('graph-updated', this.graphData)
    },

    async startProcessing() {
      if (!this.graphData || this.graphData.links.length === 0) {
        this.errorMessage = '没有关系数据需要处理'
        return
      }

      // 调试信息
      console.log('开始处理 - selectedFile:', this.selectedFile)
      console.log('开始处理 - graphData:', this.graphData)
      console.log('开始处理 - graphData.originalFile:', this.graphData?.originalFile)
      console.log('开始处理 - graphData keys:', this.graphData ? Object.keys(this.graphData) : 'null')

      // 检查是否有文件数据
      // 如果有selectedFile，直接使用
      // 如果有graphData但没有selectedFile，说明是从sessionStorage加载的，需要重新上传文件
      if (!this.selectedFile) {
        console.log('没有selectedFile，需要重新上传文件')
        this.errorMessage = '文件数据已丢失，请重新上传CSV文件以继续处理。'
        return
      }

      this.isProcessingRelationships = true
      this.clearError()

      try {
        // 首先检查后端服务是否可用
        try {
          const healthResponse = await fetch(`${this.backendUrl}/api/health`, {
            method: 'GET',
            timeout: 5000
          })
          if (!healthResponse.ok) {
            throw new Error('后端服务不可用')
          }
        } catch (healthError) {
          throw new Error('无法连接到后端服务，请确保Graph Backend正在运行 (http://localhost:5000)')
        }

        // 准备请求数据
        const formData = new FormData()
        
        // 使用selectedFile（已经确保存在）
        formData.append('file', this.selectedFile)
        
        formData.append('relationships', JSON.stringify(this.graphData.links))
        formData.append('nodes', JSON.stringify(this.graphData.nodes))

        // 调用后端API处理CSV数据
        const response = await fetch(`${this.backendUrl}/api/process-csv-with-relationships`, {
          method: 'POST',
          body: formData
        })

        if (!response.ok) {
          throw new Error(`HTTP错误: ${response.status}`)
        }

        const result = await response.json()
        
        // 调试信息
        console.log('后端API响应:', result)

        if (!result.success) {
          throw new Error(result.message || '后端处理失败')
        }

        // 处理成功，触发页面跳转事件
        console.log('触发跳转事件...')
        this.$emit('processing-completed', {
          message: 'CSV数据处理完成！正在跳转到三维图谱页面...',
          type: 'success',
          newGraphData: result.data,
          shouldNavigate: true
        })
        
      } catch (error) {
        console.error('处理CSV数据时出错:', error)
        
        let errorMessage = '处理失败'
        if (error.message.includes('Failed to fetch')) {
          errorMessage = '无法连接到后端服务，请确保Graph Backend正在运行 (http://localhost:5000)'
        } else if (error.message.includes('HTTP错误: 500')) {
          errorMessage = '后端服务器内部错误，请检查后端日志'
        } else if (error.message.includes('HTTP错误: 404')) {
          errorMessage = '后端API接口不存在，请检查后端服务配置'
        } else if (error.message.includes('HTTP错误: 413')) {
          errorMessage = '文件过大，请选择较小的CSV文件'
        } else {
          errorMessage = `处理失败: ${error.message}`
        }
        
        this.errorMessage = errorMessage
        
        // 触发错误事件
        this.$emit('processing-completed', {
          message: errorMessage,
          type: 'error'
        })
      } finally {
        this.isProcessingRelationships = false
      }
    }
  }
}
</script>

<style scoped>
.csv-graph-uploader {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.upload-section {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 8px;
}

.upload-section h3 {
  margin-bottom: 20px;
  color: #333;
  text-align: center;
}

.upload-area {
  border: 2px dashed #ccc;
  border-radius: 8px;
  padding: 40px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s ease;
  background-color: #fafafa;
}

.upload-area:hover {
  border-color: #007bff;
  background-color: #f0f8ff;
}

.upload-area.drag-over {
  border-color: #007bff;
  background-color: #e3f2fd;
}

.upload-content {
  color: #666;
}

.upload-icon {
  font-size: 48px;
  margin-bottom: 15px;
}

.upload-hint {
  font-size: 14px;
  color: #999;
  margin-top: 10px;
}

.processing-content {
  color: #007bff;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 15px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.file-info {
  margin-top: 15px;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 5px;
  border-left: 4px solid #007bff;
}

.file-info p {
  margin: 5px 0;
}

.file-actions {
  margin-top: 15px;
  display: flex;
  gap: 10px;
  justify-content: center;
}

.graph-section {
  margin-top: 30px;
}

.graph-stats {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 8px;
}

.graph-stats h4 {
  margin-bottom: 15px;
  color: #333;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 15px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background-color: white;
  border-radius: 5px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.stat-label {
  font-weight: 500;
  color: #666;
}

.stat-value {
  font-weight: bold;
  color: #007bff;
}

.graph-container {
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.error-message {
  margin-top: 20px;
  padding: 15px;
  background-color: #f8d7da;
  border: 1px solid #f5c6cb;
  border-radius: 5px;
  color: #721c24;
}

.error-message h4 {
  margin-bottom: 10px;
}

.backend-warning {
  margin-top: 20px;
  padding: 15px;
  background-color: #fff3cd;
  border: 1px solid #ffeaa7;
  border-radius: 5px;
  color: #856404;
}

.backend-warning h4 {
  margin-bottom: 10px;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s ease;
}

.btn-primary {
  background-color: #007bff;
  color: white;
}

.btn-primary:hover:not(:disabled) {
  background-color: #0056b3;
}

.btn-primary:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
}

.btn-secondary {
  background-color: #6c757d;
  color: white;
}

.btn-secondary:hover {
  background-color: #545b62;
}

/* 关系管理样式 */
.relationship-management {
  margin-top: 30px;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 8px;
}

.relationship-management h3 {
  margin-bottom: 20px;
  color: #000000;
}

.add-relationship {
  margin-bottom: 30px;
  padding: 20px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.add-relationship h4 {
  margin-bottom: 15px;
  color: #333;
}

.form-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.form-select, .form-input {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
  min-width: 120px;
}

.form-select:focus, .form-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 2px rgba(0,123,255,0.25);
}

.relationship-list {
  padding: 20px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.relationship-list h4 {
  margin-bottom: 15px;
  color: #000000;
}

.table-container {
  overflow-x: auto;
}

.relationship-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.relationship-table th,
.relationship-table td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #ddd;
  color: #000000;
}

.relationship-table th {
  background-color: #f8f9fa;
  font-weight: 600;
  color: #000000;
}

.relationship-table tr:hover {
  background-color: #f5f5f5;
}

.relationship-input {
  width: 120px;
  padding: 4px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  text-align: left;
}

.btn-sm {
  padding: 4px 8px;
  font-size: 12px;
}

.btn-danger {
  background-color: #dc3545;
  color: white;
}

.btn-danger:hover {
  background-color: #c82333;
}

.btn-success {
  background-color: #28a745;
  color: white;
}

.btn-success:hover:not(:disabled) {
  background-color: #218838;
}

.btn-success:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
}

.btn-lg {
  padding: 12px 24px;
  font-size: 16px;
  font-weight: 600;
}

.process-actions {
  margin-top: 20px;
  text-align: center;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 8px;
  border: 2px dashed #dee2e6;
}

.process-hint {
  margin-top: 10px;
  color: #6c757d;
  font-size: 14px;
  margin-bottom: 0;
}

.loading-spinner-small {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid #ffffff;
  border-top: 2px solid transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-right: 8px;
}

@media (max-width: 768px) {
  .csv-graph-uploader {
    padding: 10px;
  }
  
  .upload-area {
    padding: 20px;
  }
  
  .stats-grid {
    grid-template-columns: 1fr;
  }

  .form-row {
    flex-direction: column;
    align-items: stretch;
  }

  .form-select, .form-input {
    min-width: auto;
    width: 100%;
  }

  .relationship-table {
    font-size: 12px;
  }

  .relationship-table th,
  .relationship-table td {
    padding: 8px;
  }
}
</style>
